import * as echarts from 'echarts';
import type { Channel, ChartConfig, ParamsConfig, MarkPoint } from '@/types/chart';

/**
 * 根据通道配置生成多Grid ECharts配置
 * @param config 图表整体配置
 * @param channels 选中的通道列表
 * @param params 参数配置（用于绘制警戒线）
 * @param scrollPosition 滚动位置 (0-100)，用于多Grid滚动
 * @returns ECharts配置对象
 */
export function generateMultiGridEChartsOption(
  config: ChartConfig,
  channels: Channel[],
  params?: ParamsConfig,
  scrollPosition: number = 0
): echarts.EChartsOption {
  const option: echarts.EChartsOption = {
    title: config.title ? {
      text: config.title,
      left: 'center',
      textStyle: {
        fontSize: 16,
        fontWeight: 'bold'
      }
    } : undefined,
    tooltip: config.tooltip || {
      trigger: 'axis',
      axisPointer: {
        type: 'cross',
        crossStyle: {
          color: '#999'
        }
      },
      backgroundColor: 'rgba(255,255,255,0.9)',
      borderColor: '#ccc',
      borderWidth: 1,
      textStyle: {
        color: '#333'
      }
    },
    legend: config.legend || {
      data: [],
      top: '5%',
      textStyle: {
        fontSize: 12
      }
    },
    grid: [],
    xAxis: [],
    yAxis: [],
    series: [],
    backgroundColor: '#f8f9fa',
    dataZoom: [
      {
        type: 'inside',
        start: 0,
        end: 100
      },
      {
        type: 'slider',
        show: true,
        start: 0,
        end: 100,
        height: 20,
        bottom: 10
      }
    ]
  };

  // 若无选中通道，直接返回空配置
  if (channels.length === 0) return option;

  // 为需要合并显示的通道创建分组映射
  // 将 X1工支 和 X2非支 合并到同一个坐标轴
  // 将 接触力1 和 接触力2 合并到同一个坐标轴
  // 将 加速度1 和 加速度2 合并到同一个坐标轴
  const channelGroups: { [key: string]: Channel[] } = {};
  const processedChannels: Channel[] = [];

  channels.forEach((channel) => {
    if (channel.name === 'X1工支' || channel.name === 'X2非支') {
      // 将工支和非支归为一组
      if (!channelGroups['拉出值']) {
        channelGroups['拉出值'] = [];
        // 创建一个虚拟的组通道用于布局
        processedChannels.push({
          name: '拉出值',
          unit: 'mm',
          min: -600,
          max: 600,
          color: '#91CC75',
          selected: true,
          type: 'line'
        });
      }
      channelGroups['拉出值'].push(channel);
    } else if (channel.name === '接触力1' || channel.name === '接触力2') {
      // 将接触力1和接触力2归为一组
      if (!channelGroups['接触力']) {
        channelGroups['接触力'] = [];
        processedChannels.push({
          name: '接触力',
          unit: 'N',
          min: 0,
          max: 300,
          color: '#73C0DE',
          selected: false,
          type: 'line'
        });
      }
      channelGroups['接触力'].push(channel);
    } else if (channel.name === '加速度1' || channel.name === '加速度2') {
      // 将加速度1和加速度2归为一组
      if (!channelGroups['加速度']) {
        channelGroups['加速度'] = [];
        processedChannels.push({
          name: '加速度',
          unit: 'm/s²',
          min: 0,
          max: 50,
          color: '#3BA272',
          selected: false,
          type: 'line'
        });
      }
      channelGroups['加速度'].push(channel);
    } else {
      // 其他通道保持独立
      processedChannels.push(channel);
    }
  });

  // 创建扩展的系列列表
  const expandedSeries: any[] = [];
  const legendData: string[] = [];

  processedChannels.forEach((channel, processedIndex) => {
    const originalChannelIndex = channels.findIndex(ch => ch.name === channel.name);

    if (channel.name === '拉出值' && channelGroups['拉出值']) {
      // 拉出值组：为工支和非支创建两条线
      const groupChannels = channelGroups['拉出值'];
      groupChannels.forEach((groupChannel) => {
        expandedSeries.push({
          channel,
          name: groupChannel.name,
          dataKey: groupChannel.name === 'X1工支' ? 'X1' : 'X2',
          color: groupChannel.color,
          originalIndex: processedIndex
        });
        legendData.push(groupChannel.name);
      });
    } else if (channel.name === '接触力' && channelGroups['接触力']) {
      // 接触力组：为接触力1和接触力2创建两条线
      const groupChannels = channelGroups['接触力'];
      groupChannels.forEach((groupChannel) => {
        expandedSeries.push({
          channel,
          name: groupChannel.name,
          dataKey: groupChannel.name === '接触力1' ? 'fPressList1' : 'fPressList2',
          color: groupChannel.color,
          originalIndex: processedIndex
        });
        legendData.push(groupChannel.name);
      });
    } else if (channel.name === '加速度' && channelGroups['加速度']) {
      // 加速度组：为加速度1和加速度2创建两条线
      const groupChannels = channelGroups['加速度'];
      groupChannels.forEach((groupChannel) => {
        expandedSeries.push({
          channel,
          name: groupChannel.name,
          dataKey: groupChannel.name === '加速度1' ? 'fVibrationList1' : 'fVibrationList2',
          color: groupChannel.color,
          originalIndex: processedIndex
        });
        legendData.push(groupChannel.name);
      });
    } else if (channel.name === '导高') {
      // 导高图表绘制两条线
      expandedSeries.push({
        channel,
        name: '导高线1',
        dataKey: 'Y1',
        color: channel.color,
        originalIndex: processedIndex
      });
      expandedSeries.push({
        channel,
        name: '导高线2',
        dataKey: 'Y1_2',
        color: '#3F51B5',
        originalIndex: processedIndex
      });
      legendData.push('导高线1', '导高线2');
    } else if (channel.name === '磨耗表') {
      // 磨耗表图表绘制两条线
      expandedSeries.push({
        channel,
        name: '磨耗表线1',
        dataKey: 'MoHaoList',
        color: channel.color,
        originalIndex: processedIndex
      });
      expandedSeries.push({
        channel,
        name: '磨耗表线2',
        dataKey: 'MoHaoList_2',
        color: '#E91E63',
        originalIndex: processedIndex
      });
      legendData.push('磨耗表线1', '磨耗表线2');
    } else {
      // 其他图表保持单线
      expandedSeries.push({
        channel,
        name: channel.name,
        dataKey: getDataKeyForChannel(channel.name),
        color: channel.color,
        originalIndex: processedIndex
      });
      legendData.push(channel.name);
    }
  });

  // 更新图例数据
  (option.legend as any).data = legendData;

  // 计算每个 Grid 的垂直布局
  const maxVisibleGrids = 3; // 最多同时显示3个坐标轴
  const totalGrids = processedChannels.length;
  const needScroll = totalGrids > maxVisibleGrids;

  // 每个grid的实际高度（百分比）
  const singleGridHeight = (90 - 8) / maxVisibleGrids; // 每个grid占27%左右
  const gridMargin = 1;

  // 根据滚动位置计算起始索引
  // scrollPosition: 0-100，表示滚动条的位置
  const scrollOffset = needScroll
    ? (scrollPosition / 100) * (totalGrids - maxVisibleGrids)
    : 0;

  processedChannels.forEach((channel, channelIndex) => {
    const gridId = `grid_${channelIndex}`;

    // 计算当前 grid 的实际位置（考虑滚动偏移）
    const visualIndex = channelIndex - scrollOffset;
    const gridTop = `${12 + visualIndex * (singleGridHeight + gridMargin)}%`;
    const gridHeight_actual = `${singleGridHeight - gridMargin}%`;

    // 判断当前 grid 是否在可视区域内
    // 扩大可见范围，确保最后一个grid完全可见
    const isVisible = visualIndex >= -0.5 && visualIndex < maxVisibleGrids;

    // 只为可视区域的 grid 创建配置，优化性能
    if (!isVisible && needScroll) {
      // 对于不可见的 grid，仍然需要添加占位符以保持索引一致
      // 但设置为不显示
      (option.grid as any[]).push({
        id: gridId,
        show: false,
        top: '-100%', // 移出视图
        height: '0%',
        left: '0%',
        right: '0%'
      });

      (option.xAxis as any[]).push({
        type: 'category',
        gridIndex: channelIndex,
        show: false
      });

      (option.yAxis as any[]).push({
        type: 'value',
        gridIndex: channelIndex,
        show: false
      });

      return; // 跳过系列创建
    }

    // 1. Grid 布局
    (option.grid as any[]).push({
      id: gridId,
      top: gridTop,
      height: gridHeight_actual,
      left: '8%',
      right: needScroll ? '50px' : '5%', // 有滚动条时留出更多空间
      containLabel: true,
      backgroundColor: '#ffffff',
      borderColor: '#e0e0e0',
      borderWidth: 1,
      show: true
    });

    // 2. X 轴
    // 计算最后一个可见的 grid
    const lastVisibleIndex = Math.min(
      Math.floor(scrollOffset + maxVisibleGrids),
      totalGrids - 1
    );
    const isLastVisible = channelIndex === lastVisibleIndex;

    (option.xAxis as any[]).push({
      type: 'category',
      data: config.xAxisData || [],
      gridIndex: channelIndex,
      axisLabel: {
        show: isLastVisible, // 只有最后一个可见的显示标签
        fontSize: 10,
        color: '#666'
      },
      axisLine: {
        show: true,
        lineStyle: {
          color: '#d0d0d0'
        }
      },
      axisTick: {
        show: isLastVisible, // 只有最后一个可见的显示刻度
        lineStyle: {
          color: '#d0d0d0'
        }
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#e8e8e8',
          type: 'solid',
          width: 0.5
        }
      },
    });

    // 3. Y 轴
    (option.yAxis as any[]).push({
      type: 'value',
      gridIndex: channelIndex,
      name: `${channel.name}`,
      nameLocation: 'middle',
      nameTextStyle: {
        padding: [0, 0, 20, 0],
        fontSize: 11,
        color: channel.color,
        fontWeight: 'bold'
      },
      min: channel.min,
      max: channel.max,
      axisLine: {
        show: true,
        lineStyle: {
          color: channel.color,
          width: 2
        }
      },
      axisLabel: {
        formatter: `{value}${channel.unit}`,
        fontSize: 9,
        color: '#666'
      },
      axisTick: {
        show: true,
        lineStyle: {
          color: channel.color
        }
      },
      splitLine: {
        show: true,
        lineStyle: {
          color: '#e8e8e8',
          type: 'solid',
          width: 0.5
        }
      }
    });

    // 4. 系列 - 为当前通道添加相应的系列
    const channelSeries = expandedSeries.filter(s => s.originalIndex === channelIndex);
    channelSeries.forEach(seriesConfig => {
      (option.series as any[]).push({
        name: seriesConfig.name,
        type: channel.type || 'line',
        xAxisIndex: channelIndex,
        yAxisIndex: channelIndex,
        data: [], // 实际数据需从外部传入
        itemStyle: { color: seriesConfig.color },
        lineStyle: {
          color: seriesConfig.color,
          width: 2
        },
        showSymbol: false,
        progressive: 200,
        animation: false, // 禁用动画提高性能
        smooth: false,
        connectNulls: false, // 不连接null值，断开显示
        ...(channel.type === 'bar' && { barWidth: '60%' }),
      });
    });
  });

  return option;

  // 辅助函数：根据通道名称获取数据键
  function getDataKeyForChannel(channelName: string): string {
    switch (channelName) {
      case '速度': return 'SpeedList';
      case '网压': return 'fVot';
      default: return 'X1';
    }
  }
}

/**
 * 为指定通道添加警戒线
 * @param option ECharts配置对象
 * @param channelIndex 通道索引
 * @param channelName 通道名称
 * @param params 参数配置
 */
export function addWarningLines(
  option: echarts.EChartsOption,
  channelIndex: number,
  channelName: string,
  params: ParamsConfig
): void {
  const series = (option.series as any[])[channelIndex];
  if (!series) return;

  let markLineData: any[] = [];

  // 根据通道名称添加相应的警戒线
  if (channelName.includes('拉出值') || channelName === 'X1工支' || channelName === 'X2非支') {
    markLineData = [
      {
        yAxis: params.xdefault,
        lineStyle: { color: '#FFA500', width: 2 }, // 橙色预警线
        label: { formatter: '预警线', position: 'end' }
      },
      {
        yAxis: -params.xdefault,
        lineStyle: { color: '#FFA500', width: 2 }
      },
      {
        yAxis: params.xpolice,
        lineStyle: { color: '#FF0000', width: 2 }, // 红色超限线
        label: { formatter: '超限线', position: 'end' }
      },
      {
        yAxis: -params.xpolice,
        lineStyle: { color: '#FF0000', width: 2 }
      }
    ];
  } else if (channelName.includes('导高')) {
    markLineData = [
      {
        yAxis: params.ydefault + params.yvariable,
        lineStyle: { color: '#FFA500', width: 2 },
        label: { formatter: '预警线', position: 'end' }
      },
      {
        yAxis: params.ydefault - params.yvariable,
        lineStyle: { color: '#FFA500', width: 2 }
      },
      {
        yAxis: params.ydefault + params.ypolice,
        lineStyle: { color: '#FF0000', width: 2 },
        label: { formatter: '超限线', position: 'end' }
      },
      {
        yAxis: params.ydefault - params.ypolice,
        lineStyle: { color: '#FF0000', width: 2 }
      }
    ];
  }

  if (markLineData.length > 0) {
    series.markLine = {
      silent: true,
      data: markLineData
    };
  }
}

/**
 * 为指定通道添加标记点
 * @param option ECharts配置对象
 * @param channelIndex 通道索引
 * @param markPoints 标记点数据
 * @param pointType 标记点类型：'support'支柱点 | 'suspension'吊悬点
 */
export function addMarkPoints(
  option: echarts.EChartsOption,
  channelIndex: number,
  markPoints: MarkPoint[],
  pointType: 'support' | 'suspension'
): void {
  const series = (option.series as any[])[channelIndex];
  if (!series || markPoints.length === 0) return;

  const pointConfig = {
    support: {
      symbol: 'triangle',
      symbolRotate: 180,
      symbolSize: 20,
      color: '#FF0000'
    },
    suspension: {
      symbol: 'circle',
      symbolSize: 12,
      color: '#FF0000'
    }
  } as const;

  const config = pointConfig[pointType];

  const markPointConfig: any = {
    itemStyle: { color: config.color },
    symbol: config.symbol,
    symbolSize: config.symbolSize,
    data: markPoints
  };

  // 只有支柱点类型才有旋转属性
  if (pointType === 'support' && 'symbolRotate' in config) {
    markPointConfig.symbolRotate = config.symbolRotate;
  }

  series.markPoint = markPointConfig;
}

/**
 * 数据范围过滤器
 * @param min 最小值
 * @param max 最大值
 * @param data 原始数据
 * @returns 过滤后的数据
 */
export function processData(min: number, max: number, data: number[]): (number | null)[] {
  return data.map(value => {
    return (value >= min && value <= max) ? value : null;
  });
}